Skip to content

feat: add tcp relay using websocket#42

Open
jj28-arch wants to merge 1 commit intomasterking32:python_testingfrom
jj28-arch:python_testing
Open

feat: add tcp relay using websocket#42
jj28-arch wants to merge 1 commit intomasterking32:python_testingfrom
jj28-arch:python_testing

Conversation

@jj28-arch
Copy link
Copy Markdown

Add WebSocket TCP Relay Support

Summary

This PR adds full TCP tunneling support over WebSocket relays.

Previously, the project only supported HTTP-based relay traffic through Google Apps Script and optional exit nodes. With this change, SOCKS5 TCP traffic can now be forwarded through WebSocket-based TCP relays deployed on Cloudflare Workers or Deno Deploy.

Features

  • WebSocket TCP tunneling
  • SOCKS5 TCP CONNECT support
  • Cloudflare Workers TCP relay support
  • Deno Deploy TCP relay support
  • Optional domain fronting support
  • Bidirectional raw TCP proxying
  • Keepalive ping/pong
  • SSH-friendly low latency (TCP_NODELAY)

Added

Client

  • New tcp_ws_relay configuration block
  • Async WebSocket TCP tunnel implementation
  • RFC6455 frame encoder/decoder
  • TLS + optional domain fronting support

Relays

  • Added TCP relay support to:

    • apps_script/cloudflare_worker.js
    • apps_script/deno_deploy.ts

Example Config

"tcp_ws_relay": {
  "enabled": true,
  "ws_url": "wss://your-relay/tcp",
  "auth_key": "CHANGE_ME",
  "front_domain": null,
  "front_ip": null,
  "connect_timeout": 15,
  "ping_interval": 20
}

Notes

  • Existing HTTP relay functionality remains unchanged
  • TCP relay is optional and disabled by default
  • No external Python dependencies added

@ZoodSood
Copy link
Copy Markdown

ZoodSood commented May 5, 2026

Appreciate the effort!

That said, I think this is a bit outside the scope of what this project is trying to do.

To give some background: the main folks who'd benefit from a tool like this are users in places like Iran, where access to Western services is super limited — basically just Google and GitHub (yep, not even Cloudflare!). So an HTTP relay that hides traffic inside Google searches actually makes a lot of sense for them.

A TCP/WebSocket relay with “optional domain fronting,” on the other hand, is effectively another general‑purpose proxy solution. While there’s nothing wrong with that, I think such a feature would be better maintained in its own dedicated repository.

I'd rather keep MasterHTTP focused on doing one thing really well and keeping deployment as dead-simple as possible. Let's keep it lean and on track.

@jj28-arch
Copy link
Copy Markdown
Author

jj28-arch commented May 5, 2026

Appreciate the effort!

That said, I think this is a bit outside the scope of what this project is trying to do.

To give some background: the main folks who'd benefit from a tool like this are users in places like Iran, where access to Western services is super limited — basically just Google and GitHub (yep, not even Cloudflare!). So an HTTP relay that hides traffic inside Google searches actually makes a lot of sense for them.

A TCP/WebSocket relay with “optional domain fronting,” on the other hand, is effectively another general‑purpose proxy solution. While there’s nothing wrong with that, I think such a feature would be better maintained in its own dedicated repository.

I'd rather keep MasterHTTP focused on doing one thing really well and keeping deployment as dead-simple as possible. Let's keep it lean and on track.

Thanks for your attention. I know about the level of censorship in Iran. I live in Iran too. The thing is censorship is leveled. Currently only google is accessible, but if the level decrease only a bit, cloudflare would be accessible and this method could be easily used. Protocols like ssh which are almost mandatory in the jobs of many people including myself, could be accessible using this method. Also the config is as simple as it gets. The only difference is you should deploy a different script. That said, since the name of the project is masterhttprelay, the functionality of my changes might not totally match the name of the repository.

@ZoodSood
Copy link
Copy Markdown

ZoodSood commented May 6, 2026

Thanks for your attention. I know about the level of censorship in Iran. I live in Iran too. The thing is censorship is leveled. Currently only google is accessible, but if the level decrease only a bit, cloudflare would be accessible and this method could be easily used. Protocols like ssh which are almost mandatory in the jobs of many people including myself, could be accessible using this method. Also the config is as simple as it gets. The only difference is you should deploy a different script.

You are right about the levels of censorship. Guess we'll have to see how things develop. But then, if Cloudflare becomes accessible, the good-old name server records proxy also becomes accessible which already powers millions of V2Ray and MTProto tunnels.

That said, since the name of the project is masterhttprelay, the functionality of my changes might not totally match the name of the repository.

The README also mentions: "This project is centered on the Apps Script relay."

@DarkestViolet
Copy link
Copy Markdown

Hi, thank you for your effort in advance. I need to use this but I'm not an expert. Can you explain how exactly to deploy deno.tcp.relay.ts on Deno? I only get URLs that end with deno.net.

@jj28-arch
Copy link
Copy Markdown
Author

Hi, thank you for your effort in advance. I need to use this but I'm not an expert. Can you explain how exactly to deploy deno.tcp.relay.ts on Deno? I only get URLs that end with deno.net.

Hi.
The url is ok, you just need to change the http:// stuff to wss:// and also add a /ws to the end. Just like how it looks in the example.json but with your own domain name

@decisiv31
Copy link
Copy Markdown

Thank you for your efforts @jj28-arch. This is a much-needed functionality for me. Is it possible to disguise SOCKS5 TCP CONNECT as an HTTP request client-side, and then send it through Google App Script and then send it to a VPS server which can un-disguise it and send back a disguised response? Something like this:

request:
End-user app ---(tcp)---> MHR client ---(http)---> App Script ---(http)---> VPS ---(tcp)---> Target

response:
Target ---(tcp)---> VPS ---(http)---> App Script ---(http)---> MHR client ---(tcp)---> End-user app

I'm very new to Google App Script. I'm not sure if this is possible. I guess it would have been implemented so far if that was possible, but I just wanna make sure.

@jj28-arch
Copy link
Copy Markdown
Author

jj28-arch commented May 8, 2026

Thank you for your efforts @jj28-arch. This is a much-needed functionality for me. Is it possible to disguise SOCKS5 TCP CONNECT as an HTTP request client-side, and then send it through Google App Script and then send it to a VPS server which can un-disguise it and send back a disguised response? Something like this:

request: End-user app ---(tcp)---> MHR client ---(http)---> App Script ---(http)---> VPS ---(tcp)---> Target

response: Target ---(tcp)---> VPS ---(http)---> App Script ---(http)---> MHR client ---(tcp)---> End-user app

I'm very new to Google App Script. I'm not sure if this is possible. I guess it would have been implemented so far if that was possible, but I just wanna make sure.

Hi @decisiv31
That's exactly what Iam working on now.
I'm implementing two possible modes:

  1. app_script + vps
    which embeds tcp traffic inside http request and sends it to the app_script.
    then the app_script sends the request containing the tcp embedded data to a vps.
    the vps extracts the tcp data, creates the connection, sends the data, receives the response, embeds the response into http request, sends back to the app_script as http response, and the app_script sends it back to the client.
    the client extract tcp data from the http response and uses the data.

  2. app_script + cloudflare worker
    This is almost the same as above, which a slight difference.
    The cloudflare worker extracts the tcp data from the http request, but uses websocket to route it.

My current challenges are:

  1. tcp creates connections, It is hard to maintain the state of connections using http request and response.
  2. app_script has limited connection time (I think around 6 minutes) so connections are only persistant for 6 minutes.

I hope I can finish these soon.
https://github.com/jj28-arch/MasterHttpRelayVPN/tree/python_testing_tcp_relay
this is the fork I'm working on, Please feel free to checkout or help fixing the current challengs.
The code is totally unfinished now.

Also checkout https://github.com/Kianmhz/GooseRelayVPN
kianmhz implemented the vps mode but the rate limit issue persists.

@ZoodSood
Copy link
Copy Markdown

ZoodSood commented May 8, 2026

@jj28-arch your WIP ideas are very interesting.

My current challenges are:

  1. tcp creates connections, It is hard to maintain the state of connections using http request and response.
  2. app_script has limited connection time (I think around 6 minutes) so connections are only persistent for 6 minutes.

GAS also has the following limits applied to all scripts deployed by a Google Account:

  • Total runtime: 90 minutes/day
  • URL Fetch: 20,000/day
  • Size: 100 MB/request

Normally HTTP requests are not persistent connections. They open and close quickly, but having TCP connections remaining open easily burns through the runtime quota.

One thing I noticed is that you can tunnel GAS > CF > SSH (or Psiphon) and that lowers the request count, but still affects runtime and bandwidth very heavily. Using multiple Google Accounts, each deploying multiple scripts for optimum speed, could theoretically give us enough quota to last a full working day.

@abolix
Copy link
Copy Markdown
Collaborator

abolix commented May 8, 2026

The thing is that in MHR project we mainly focused on H1.1 and H2, because the whole core of the project is based on MITM.

If I understood you correctly, we need to fully disabled MITM and go for Raw TCP which needs a big core change that I don't think it's necessary right now.

have you looked at Goose Project ?

@jj28-arch
Copy link
Copy Markdown
Author

The thing is that in MHR project we mainly focused on H1.1 and H2, because the whole core of the project is based on MITM.

If I understood you correctly, we need to fully disabled MITM and go for Raw TCP which needs a big core change that I don't think it's necessary right now.

have you looked at Goose Project ?

Didn't have the time unfortunately. I just found out about Goose today. I will take a closer look at it tonight. Maybe combine the ideas to minimize traffic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants